package com.edu.test;

import com.edu.bean.User;
import org.junit.Test;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class MyTest03 {

    /**
     *  获取 Method对象
     *      首先需要需要获取到 Class对象
     *      获取Method对象的方式
     */
    @Test
    public void test01(){
        Class clazz = User.class;
        //1.getMethods 获取 所有的 公有方法(该类和该类的父类的方法)
//        Method[] methods = clazz.getMethods();
//        for (Method method : methods) {
//            System.out.println(method.getName());
//            System.out.println("---");
//        }
        //2.getDeclaredMethods 获取所有的方法（包括公有和私有方法）(不包括父类的)
//        Method[] methods1 = clazz.getDeclaredMethods();
//        for (Method method : methods1) {
//            System.out.println(method.getName());
//        }
        //3. getMethod(参数名,形参类型) 获取指定方法名和参数类型的公有方法
        try {
            Method method = clazz.getMethod("sayHi");
            System.out.println(method.getName());
        } catch (NoSuchMethodException e) {
            System.out.println("该方法不存在，或者不可被访问");
            e.printStackTrace();
        }

        //4 getDeclaredMethod 获取指定方法名的方法
        try {
            Method method = clazz.getDeclaredMethod("innerMethod");
            System.out.println(method.getName());
        } catch (NoSuchMethodException e) {
            System.out.println("该方法不存在，或者不可被访问");
            e.printStackTrace();
        }

    }

    /**
     *     Method对象的一些get方法
     */
    @Test
    public void test02(){
        Class clazz = User.class;

        try {
            Method method = clazz.getMethod("sayHi",String.class);
//            Method method = clazz.getMethod("toString");
            System.out.println("方法的名字"+method.getName());
            System.out.println("方法声明位置"+method.getDeclaringClass());
            System.out.println("方法抛出的异常类型"+method.getExceptionTypes().length);
            System.out.println("方法访问修饰符:"+method.getModifiers());
            System.out.println("方法的参数个数"+method.getParameterCount());
            System.out.println("方法的参数类型"+method.getParameterTypes());
            System.out.println("方法的返回值类型"+method.getReturnType());
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
    }

    /**
     * 利用反射调研方法
     */
    @Test
    public void test03() {
        Class clazz = User.class;
        User user = new User();
        user.username = "zhangsan";
        User user2 = new User();
        try {
//            Method method = clazz.getDeclaredMethod("sayHi");
//            method.invoke(user);

            Method method = clazz.getMethod("sayHi",String.class);
            method.invoke(user2,"今天星期三");

            Method method2 = clazz.getMethod("getNum");
            System.out.println(method2.invoke(user));

            Method method3 = clazz.getDeclaredMethod("innerMethod");
            method3.setAccessible(true);
            method3.invoke(user2);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }



}
